boolean checkCollisionWithEdges(int[][] _coordsA, int[][] _coordsB, int[] positionA, int[] positionB)
{
  return _checkCollision(_coordsA, _coordsB, positionA, positionB, true);
}

boolean checkCollision(int[][] _coordsA, int[][] _coordsB, int[] positionA, int[] positionB)
{
  return _checkCollision(_coordsA, _coordsB, positionA, positionB, false);
}

/**
 * Checks for the existence of the coordinates of convex polygon B inside the coordinates of convex polygon A
 * Positions are the screen positions of the first coordinate in the list of coordinates
 */
boolean _checkCollision(int[][] _coordsA, int[][] _coordsB, int[] positionA, int[] positionB, boolean detectEdges)
{
  int[][] coordsA = new int[_coordsA.length][2];
  int[][] coordsB = new int[_coordsB.length][2];
  
  // get the absolute coordinates
  for (int i = 0; i < coordsA.length; i++)
  {
    coordsA[i][0] = _coordsA[i][0] + positionA[0];
    coordsA[i][1] = _coordsA[i][1] + positionA[1];
  }
  for (int i = 0; i < coordsB.length; i++)
  {
    coordsB[i][0] = _coordsB[i][0] + positionB[0];
    coordsB[i][1] = _coordsB[i][1] + positionB[1];
  }
  
  // check for special cases
  if (coordsB.length == 1)
  {
    // both arrays are length 1
    if (coordsA.length == 1)
    {
      if (coordsA[0][0] == coordsB[0][0] && coordsA[0][1] == coordsB[0][1])
      {
        return true;
      }
      return false;
    }
    // array A should have 1 point and array B should be the shape
    int[][] tempCoords = coordsA;
    coordsA = coordsB;
    coordsB = tempCoords;
  }
  
  // check for a collision
  for (int i = 0; i < coordsA.length; i++)
  {
    if (checkPointCollision(coordsB, coordsA[i], detectEdges))
    {
      return true;
    }
  }
  
  return false;
}

/**
 * check that a point is inside a set of coordinates
 * Coordinate order matters! It must proceed clockwise!
 * @param inCoords the coordinates of the convex polygon
 * @param pos two values denoting the location of the point
 */
boolean checkPointCollision(int[][] inCoords, int[] pos, boolean detectEdges)
{
  for (int i = 0; i < inCoords.length; i++)
  {
    int[][] coords = new int[2][2];
    coords[0] = inCoords[i];
    int j = i+1;
    while (j > inCoords.length - 1)
    {
      j -= inCoords.length;
    }
    coords[1] = inCoords[j];
    
    if (!checkPointToRightOfLine(coords, pos, detectEdges))
    {
      return false;
    }
  }
  
  return true;
}

/**
 * check that a point is to the "right" of a line
 * line coordinate order matters!
 * @param lineCoords a set of two coordinates for the start and end of a line
 * @param pos two values denoting the location of the point
 */
boolean checkPointToRightOfLine(int[][] lineCoords, int[] pos, boolean detectEdges)
{
  boolean lineIsVertical = false;
  boolean lineGoesRight = false;
  float slope = 0;
  int yInterceptLine = 0;
  int yInterceptPoint = 0;
  
  // check for vertical lines
  if (lineCoords[0][0] == lineCoords[1][0])
  {
    lineIsVertical = true;
    if (!detectEdges)
    {
      if (pos[0] < lineCoords[0][0] && lineCoords[0][1] < lineCoords[1][1])
      {
        return true;
      }
      if (pos[0] > lineCoords[0][0] && lineCoords[0][1] > lineCoords[1][1])
      {
        return true;
      }
    }
    else
    {
      if (pos[0] <= lineCoords[0][0] && lineCoords[0][1] < lineCoords[1][1])
      {
        return true;
      }
      if (pos[0] >= lineCoords[0][0] && lineCoords[0][1] > lineCoords[1][1])
      {
        return true;
      }
    }
    return false;
  }
  
  // find the slope
  if (lineCoords[1][1] == lineCoords[0][1])
  {
    slope = 0;
  }
  else
  {
    slope = ((float)lineCoords[1][1] - (float)lineCoords[0][1]) / ((float)lineCoords[1][0] - (float)lineCoords[0][0]);
  }
  
  // find the yIntercepts
  yInterceptLine = lineCoords[0][1] - (int)(slope*(float)lineCoords[0][0]);
  yInterceptPoint = pos[1] - (int)(slope*(float)pos[0]);
  
  // determine if the line goes left or right
  lineGoesRight = true;
  if (lineCoords[0][0] > lineCoords[1][0])
  {
    lineGoesRight = false;
  }
  
  // right low, left high
  if (lineGoesRight)
  {
    if ((yInterceptPoint > yInterceptLine && !detectEdges) ||
        (yInterceptPoint >= yInterceptLine && detectEdges))
    {
      return true;
    }
  }
  else
  {
    if ((yInterceptPoint < yInterceptLine && !detectEdges) ||
        (yInterceptPoint <= yInterceptLine && detectEdges))
    {
      return true;
    }
  }
  
  return false;
}
